<template>
    <el-dialog :title="dialogFrom.dialogTitle" :model-value="dialogFrom.dialogVisible"
        @input:model-value="updateDialogVisible" align-center width="60%" :before-close="onCancel">
        <el-form :model="dataInfo" label-width="100px" class="demo-ruleForm">
            <el-form-item label="角色名称">
                <el-input v-model="roleName" disabled></el-input>
            </el-form-item>
            <el-form-item label="菜单选择">
                <el-tree ref="treeRef" style="width: 100%;height: 300px;overflow-y: auto;" :data="menuTreeList" :props="menuTreeProps" show-checkbox
                     node-key="id" highlight-current
                    :render-after-expand="false" @check-change="handleCheckChange" />
            </el-form-item>
        </el-form>
        <template #footer>
            <div class="dialog-footer">
                <el-button type="primary" @click="onSubmit()" :loading="loading">提交</el-button>
                <el-button @click="onCancel">取消</el-button>
            </div>
        </template>
    </el-dialog>
</template>
<script lang="ts" setup>
// -------------------------------------------------导入相关引用-------------------------------------------------
import { ref, watch } from 'vue';
import { ElMessage } from 'element-plus'
import { type TableData, editRoleMenu, roleMenuList } from '@/api/system/SysRole';
import { getTreeList, type TableData as MenuTableData } from '@/api/system/SysMenu';
// -------------------------------------------------相关参数定义-------------------------------------------------
const loading = ref(false);

const props = withDefaults(defineProps<{
    dialogFrom: DialogFrom
}>(), {
    dialogFrom: () => ({
        dialogTitle: '',
        dialogVisible: false,
        roleInfo: null,
    })
});

const treeRef = ref<any>(null);

const dataInfo = ref<{ roleId: number | null | undefined, menuIds: number[] }>({
    roleId: null,
    menuIds: [],
});


const roleName = ref<string | undefined>('');

const menuTreeProps = {
    id: 'id',
    label: 'name',
    children: 'children',
}

const menuTreeList = ref<MenuTableData[]>([]);

// ---------------------------------------------------事件定义--------------------------------------------------
const emit = defineEmits(['update:dialogFrom', 'onParentSearch']);
// -------------------------------------------------操作方法定义-------------------------------------------------
/**
 * 监听dialogFrom参数
 */
watch(() => props.dialogFrom.dialogVisible, (newValue, oldValue) => {
    if (newValue) {
        dataInfo.value.roleId = props.dialogFrom.roleInfo?.id;
        roleName.value = props.dialogFrom.roleInfo?.name;
        getMenuTreeListApi();
    }
})

/**
 * 获取菜单树列表
 */
const getMenuTreeListApi = async () => {
    await getTreeList({
        pageNum: 1,
        pageSize: 999,
    }).then((res) => {
        if (res.data.code === 200) {
            menuTreeList.value = res.data.data;
        }
    })
    await roleMenuList(props.dialogFrom.roleInfo?.id).then((res) => {
        if (res.data.code === 200) {
            const menuIdSet = new Set(dataInfo.value.menuIds);
            res.data.data.forEach((item: { roleId: number, menuId: number }) => {
                menuIdSet.add(item.menuId);
            })
            dataInfo.value.menuIds = Array.from(menuIdSet);
            treeRef.value!.setCheckedKeys(dataInfo.value.menuIds, false)
        }
    })
}

const handleCheckChange = (data: MenuTableData, checked: boolean, indeterminate: boolean) => {
    const menuIdSet = new Set(dataInfo.value.menuIds);

    if (checked) {
        menuIdSet.add(data.id);
    } else {
        menuIdSet.delete(data.id);
    }

    dataInfo.value.menuIds = Array.from(menuIdSet);
}

/**
 * 提交表单
 */
const onSubmit = async () => {
    loading.value = true;
    editRoleMenu(dataInfo.value).then((res) => {
        loading.value = false;
        if (res.data.code === 200) {
            ElMessage.success({
                message: '菜单分配成功',
                type: 'success'
            })
            onCancel();
        }
    })
}

/**
 * 关闭弹窗
 */
const onCancel = () => {
    emit('update:dialogFrom', {
        dialogVisble: false,
        dialogTitle: '',
        infoId: null
    });
    emit('onParentSearch');
    resetFrom();
}

/**
 * 重置表单
 */
const resetFrom = () => {
    menuTreeList.value = []
    dataInfo.value = {
        roleId: null,
        menuIds: [],
    }
}

/**
 * 更新弹窗显示状态
 * @param dialogFromParams 
 * @returns void
 */
const updateDialogVisible = (dialogFromParams: DialogFrom) => {
    emit('update:dialogFrom', dialogFromParams);
}
// -------------------------------------------------实体定义区-------------------------------------------------
export interface DataInfo {
    roleId: number | null | undefined;
    roleName: string | undefined;
    menuId: number[];
}

/**
 * 弹窗信息
 */
export interface DialogFrom {
    dialogTitle: string;
    dialogVisible: boolean;
    roleInfo: TableData | null;
}
</script>

<style lang="scss" scoped></style>